package com.dianxin.smartpark.service.visitor.impl;

import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.*;
import cn.hutool.http.ContentType;
import com.alibaba.fastjson.JSON;
import com.chinatelecom.response.common.CommonResponseBody;
import com.chinatelecom.response.utils.BeanUtil;
import com.chinatelecom.response.utils.ResponseBodyWrapperUtil;
import com.chinatelecom.response.constant.ErrMsgEnum;

import com.chinatelecom.response.utils.StringUtils;
import com.chinatelecom.response.utils.ZipUtils;
import com.dianxin.acl.api.acl.AclFileRpcService;
import com.dianxin.acl.api.dic.DataDicRpcService;
import com.dianxin.acl.api.dto.SsoUserDTO;
import com.dianxin.acl.api.dto.SysFileDTO;
import com.dianxin.common.cache.service.RedisService;
import com.dianxin.common.oss.properties.FileUploadResponse;
import com.dianxin.common.oss.util.MinioUtil;
import com.dianxin.device.api.device.SmartParkDeviceRpcService;
import com.dianxin.device.api.device.dto.SmartDeviceDTO;
import com.dianxin.device.api.device.dto.SmartDeviceUserDTO;
import com.dianxin.device.api.device.qo.SmartDeviceRpcQO;
import com.dianxin.device.api.device.qo.SmartDeviceUserRpcQO;
import com.dianxin.smartpark.dao.dataobject.common.SmartParkAccessTime;
import com.dianxin.smartpark.dao.dataobject.common.SmartParkAccessTimeExample;
import com.dianxin.smartpark.dao.dataobject.visitor.*;
import com.dianxin.smartpark.dao.mapper.common.SmartParkAccessTimeMapper;
import com.dianxin.smartpark.dao.mapper.visitor.SmartParkStrategyConfigMapper;
import com.dianxin.smartpark.dao.mapper.visitor.SmartParkVisitorMapper;
import com.dianxin.smartpark.dao.qo.visitor.SmartParkVisitorQO;
import com.dianxin.smartpark.service.access.SmartParkDeviceUserService;
import com.dianxin.smartpark.service.common.SmartParkDeviceAuthService;
import com.dianxin.smartpark.service.common.SmartParkUserConfigService;
import com.dianxin.smartpark.service.config.MqttOptType;
import com.dianxin.smartpark.service.config.MqttTopicType;
import com.dianxin.smartpark.service.visitor.SmartParkVisitorService;
import com.dianxin.smartpark.service.vo.common.DevicePullDataVo;
import com.dianxin.smartpark.service.vo.common.MqttMessageVo;
import com.dianxin.smartpark.service.vo.common.SmartParkUserTzVO;
import com.dianxin.smartpark.service.vo.visitor.SmartParkVisitorQrVO;
import com.dianxin.smartpark.service.vo.visitor.SmartParkVisitorStaticVO;
import com.dianxin.smartpark.service.vo.visitor.SmartParkVisitorVO;
import com.dianxin.sso.client.context.UserHolderContext;
import org.apache.commons.codec.binary.Base64;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import javax.annotation.Resource;
import javax.validation.Valid;

/**
 * 访客管理业务层处理
 * 
 * @author chenjiasong
 * @date 2021-07-28
 */
@Service
public class SmartParkVisitorServiceImpl implements SmartParkVisitorService
{
    private final static Logger logger = LoggerFactory.getLogger(SmartParkVisitorServiceImpl.class);
    @Resource
    private SmartParkVisitorMapper smartParkVisitorMapper;

    @Resource
    private SmartParkStrategyConfigMapper smartParkStrategyConfigMapper;

    @Resource
    private RedisService redisService;

    @Resource
    private MinioUtil minioUtil;

    @Resource
    private AclFileRpcService aclFileRpcService;

    @Resource
    private SmartParkDeviceRpcService smartParkDeviceRpcService;

    @Resource
    private SmartParkDeviceAuthService smartParkDeviceAuthService;

    /**
     * 查询访客管理
     * 
     * @param qo 访客管理
     * @return 访客管理
     */
    @Override
    public CommonResponseBody<SmartParkVisitorVO> selectSmartParkVisitor(SmartParkVisitorQO qo)
    {
        if(StringUtils.isNull(qo.getId()) && StringUtils.isNull(qo.getVisitorIdNum())){
            return ResponseBodyWrapperUtil.fail(ErrMsgEnum.ERROR_PARAME);
        }
        SmartParkVisitorExample smartParkVisitorExample = new SmartParkVisitorExample();
        SmartParkVisitorExample.Criteria criteria = smartParkVisitorExample.createCriteria();
        if (qo.getTenantId() != null) {
            criteria.andTenantIdEqualTo(qo.getTenantId());
        }
        if(StringUtils.isNotNull(qo.getId())){
            criteria.andIdEqualTo(qo.getId());
        }

        if(StringUtils.isNotNull(qo.getVisitorIdNum())){
            criteria.andVisitorIdNumEqualTo(qo.getVisitorIdNum());
        }
        criteria.andIsDeletedEqualTo(0);
        smartParkVisitorExample.setOrderByClause("gmt_create desc");
        List<SmartParkVisitor> passRecords = smartParkVisitorMapper.selectByExample(smartParkVisitorExample);
        return ResponseBodyWrapperUtil.successWrapper(StringUtils.isNotEmpty(passRecords)?passRecords.get(0):null,SmartParkVisitorVO.class);
    }


    /**
     * 查询访客管理列表
     * 
     * @param qo 访客管理
     * @return 访客管理
     */
    @Override
    public CommonResponseBody<List<SmartParkVisitorVO>> selectSmartParkVisitorList(SmartParkVisitorQO qo)
    {
        SmartParkVisitorExample smartParkVisitorExample = new SmartParkVisitorExample();
        SmartParkVisitorExample.Criteria criteria = smartParkVisitorExample.createCriteria();
        if (qo.getTenantId() != null) {
            criteria.andTenantIdEqualTo(qo.getTenantId());
        }
        if(StringUtils.isNotNull(qo.getStatus())){
            criteria.andStatusEqualTo(qo.getStatus());
        }

        if(StringUtils.isNotNull(qo.getGmtCreate())){
            criteria.andGmtCreateGreaterThanOrEqualTo(DateUtil.beginOfDay(qo.getGmtCreate()));
            criteria.andGmtCreateLessThanOrEqualTo(DateUtil.parse(DateUtil.format(qo.getGmtCreate(), "yyyy-MM-dd")+" 23:59:59"));
        }

        if(StringUtils.isNotBlank(qo.getSerachText())){
            smartParkVisitorExample.setSerachText(qo.getSerachText());
        }
        criteria.andIsDeletedEqualTo(0);
        if (qo.getNeedPage()) {
            smartParkVisitorExample.setOrderByClause("gmt_create desc limit " + (qo.getPageIndex() - 1) * qo.getPageSize() + "," + qo.getPageSize());
        } else {
            smartParkVisitorExample.setOrderByClause("gmt_create desc");
        }
        List<SmartParkVisitor> passRecords = smartParkVisitorMapper.selectByExample(smartParkVisitorExample);
        long count = smartParkVisitorMapper.countByExample(smartParkVisitorExample);
        return ResponseBodyWrapperUtil
                .successListWrapper(passRecords, count, qo, SmartParkVisitorVO.class);
    }

    /**
     * 查询访客统计
     *
     * @param qo 访客管理
     * @return 访客管理
     */
    @Override
    public CommonResponseBody<SmartParkVisitorStaticVO> selectVisitorStatic(SmartParkVisitorQO qo)
    {
        if(StringUtils.isNull(qo.getTenantId())){
            return ResponseBodyWrapperUtil.fail(ErrMsgEnum.ERROR_PARAME);
        }
        SmartParkVisitor smartParkVisitor = new SmartParkVisitor();
        smartParkVisitor.setTenantId(qo.getTenantId());
        SmartParkVisitorStatic record = smartParkVisitorMapper.selectVisitorStatic(smartParkVisitor);
        return ResponseBodyWrapperUtil.successWrapper(record,SmartParkVisitorStaticVO.class);
    }

    /**
     * 新增访客管理
     * 
     * @param vo 访客管理
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResponseBody<String> insertSmartParkVisitor(@Valid SmartParkVisitorVO vo) throws Exception {
        //租户id
        if(StringUtils.isEmpty(vo.getTenantId())){
            return ResponseBodyWrapperUtil.fail(ErrMsgEnum.ERROR_PARAME);
        }
        if(StringUtils.isNull(vo.getOpenType())){
            return ResponseBodyWrapperUtil.fail(ErrMsgEnum.ERROR_PARAME);
        }
        if(StringUtils.isEmpty(vo.getVisitorPhoneNum())){
            return ResponseBodyWrapperUtil.fail(ErrMsgEnum.ERROR_PARAME);
        }
        if(StringUtils.isEmpty(vo.getVisitorIdNum())){
            return ResponseBodyWrapperUtil.fail(ErrMsgEnum.ERROR_PARAME);
        }
        if(StringUtils.isEmpty(vo.getVisitorIdNum())){
            return ResponseBodyWrapperUtil.fail(ErrMsgEnum.ERROR_PARAME);
        }
        if(StringUtils.isEmpty(vo.getDeviceCode())){
            return ResponseBodyWrapperUtil.fail(ErrMsgEnum.ERROR_PARAME);
        }
        if(!IdcardUtil.isValidCard(vo.getVisitorIdNum())){
            return ResponseBodyWrapperUtil.fail("身份证号码不合法","400");
        }
        SmartParkVisitorExample smartParkVisitorExample = new SmartParkVisitorExample();
        SmartParkVisitorExample.Criteria smartParkVisitorExampleCriteria = smartParkVisitorExample.createCriteria();
        smartParkVisitorExampleCriteria.andIsDeletedEqualTo(0);
        smartParkVisitorExampleCriteria.andVisitorIdNumEqualTo(vo.getVisitorIdNum());
        smartParkVisitorExampleCriteria.andVisitorPhoneNumEqualTo(vo.getVisitorPhoneNum());
        List<SmartParkVisitor> smartParkVisitors = smartParkVisitorMapper.selectByExample(smartParkVisitorExample);
        if(StringUtils.isNotEmpty(smartParkVisitors)){
            if(StringUtils.isNotEmpty(smartParkVisitors.get(0).getSourceSystem()) && smartParkVisitors.get(0).getSourceSystem().contains(vo.getDeviceCode())){
                if(DateUtil.isIn(new Date(),smartParkVisitors.get(0).getAccessStartDate(),smartParkVisitors.get(0).getAccessEndDate())){
                    return ResponseBodyWrapperUtil.fail("该访客今日已登记","400");
                }
            }
        }
        //查询该租户开门方式是否支持二维码开门
        SmartParkStrategyConfigExample smartParkStrategyConfigExample = new SmartParkStrategyConfigExample();
        SmartParkStrategyConfigExample.Criteria criteria = smartParkStrategyConfigExample.createCriteria();
        criteria.andTenantIdEqualTo(vo.getTenantId());
        List<SmartParkStrategyConfig> strategyConfigs = smartParkStrategyConfigMapper.selectByExample(smartParkStrategyConfigExample);
        if(StringUtils.isEmpty(strategyConfigs)){
            return ResponseBodyWrapperUtil.fail("访客策略没有配置","400");
        }

        SmartParkStrategyConfig strategyConfig = strategyConfigs.get(0);
        String openType = strategyConfig.getOpenType();
        if(StringUtils.isEmpty(openType) || openType.indexOf(Convert.toStr(vo.getOpenType()))==-1){
            return ResponseBodyWrapperUtil.fail("不支持此开门方式","400");
        }

        SmartParkVisitor smartParkVisitor = new SmartParkVisitor();
        try {
            BeanUtil.insertConversion(vo, smartParkVisitor);
        } catch (Exception e) {
            logger.error("", e);
        }
        smartParkVisitor.beforeInsert();
        SysFileDTO visitorPhotoFile = null;
        SysFileDTO idPhotoFile = null;
        SysFileDTO characteristicFile = null;
        //上传照片
        if(StringUtils.isNotEmpty(vo.getVisitorPhoto())){
            visitorPhotoFile = new SysFileDTO();
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] b = decoder.decodeBuffer(vo.getVisitorPhoto().replace("data:image/jpg;base64,", ""));
            String filename = IdUtil.objectId()+".png";
            FileUploadResponse visitorPhotoUploadResponse = minioUtil.uploadFile(b,"visitor-photo",filename);
            visitorPhotoFile.setBusiType(1);
            visitorPhotoFile.setFilePath(filename);
            visitorPhotoFile.setFileName(filename);
            visitorPhotoFile.setFileUrl(visitorPhotoUploadResponse.getUrlHttp());
            visitorPhotoFile.setFileExt("png");
            visitorPhotoFile.setBucketName("visitor-photo");
            visitorPhotoFile.setTenantId(vo.getTenantId());
            CommonResponseBody<SysFileDTO> dtoCommonResponseBody1 = aclFileRpcService.insertSysFile(visitorPhotoFile);
            if(!dtoCommonResponseBody1.isSuccess()){
                return ResponseBodyWrapperUtil.fail("文件插入失败","400");
            }

            visitorPhotoFile = dtoCommonResponseBody1.getData();
            if(StringUtils.isNull(visitorPhotoFile)){
                return ResponseBodyWrapperUtil.fail("文件插入失败","400");
            }
            smartParkVisitor.setVisitorPhoto(Convert.toStr(visitorPhotoFile.getId()));

        }
        //上传身份证照片
        if(StringUtils.isNotEmpty(vo.getIdPhoto())){
            idPhotoFile = new SysFileDTO();
            BASE64Decoder decoder = new BASE64Decoder();
            String filename = IdUtil.objectId()+".png";
            byte[] idB = decoder.decodeBuffer(vo.getIdPhoto().replace("data:image/jpg;base64,", ""));
            FileUploadResponse idPhotoUploadResponse = minioUtil.uploadFile(idB,"visitor-photo",filename);
            idPhotoFile.setBusiType(2);
            idPhotoFile.setFilePath(filename);
            idPhotoFile.setFileName(filename);
            idPhotoFile.setFileUrl(idPhotoUploadResponse.getUrlHttp());
            idPhotoFile.setFileExt("png");
            idPhotoFile.setTenantId(vo.getTenantId());
            idPhotoFile.setBucketName("id-photo");
            CommonResponseBody<SysFileDTO> dtoCommonResponseBody1 = aclFileRpcService.insertSysFile(idPhotoFile);
            if(!dtoCommonResponseBody1.isSuccess()){
                return ResponseBodyWrapperUtil.fail("文件插入失败","400");
            }

            idPhotoFile = dtoCommonResponseBody1.getData();
            if(StringUtils.isNull(idPhotoFile)){
                return ResponseBodyWrapperUtil.fail("文件插入失败","400");
            }
            smartParkVisitor.setIdPhoto(Convert.toStr(idPhotoFile.getId()));
        }

        if(StringUtils.isNotEmpty(vo.getCharacteristic())){
            characteristicFile = new SysFileDTO();
            String filename = IdUtil.objectId()+".data";
            byte[] characteristic = ZipUtils.hexStr2ByteArr(ZipUtils.gunzip(vo.getCharacteristic()));
            FileUploadResponse characteristicUploadResponse = minioUtil.uploadFile(characteristic,"visitor-characteristic",filename);
            smartParkVisitor.setCharacteristic(characteristicUploadResponse.getUrlHttp());
            characteristicFile.setBusiType(3);
            characteristicFile.setFilePath(filename);
            characteristicFile.setFileName(filename);
            characteristicFile.setFileUrl(characteristicUploadResponse.getUrlHttp());
            characteristicFile.setFileExt("data");
            characteristicFile.setTenantId(vo.getTenantId());
            characteristicFile.setBucketName("visitor-characteristic");
            CommonResponseBody<SysFileDTO> dtoCommonResponseBody1 = aclFileRpcService.insertSysFile(characteristicFile);
            if(!dtoCommonResponseBody1.isSuccess()){
                return ResponseBodyWrapperUtil.fail("文件插入失败","400");
            }

            characteristicFile = dtoCommonResponseBody1.getData();
            if(StringUtils.isNull(characteristicFile)){
                return ResponseBodyWrapperUtil.fail("文件插入失败","400");
            }
            smartParkVisitor.setCharacteristic(Convert.toStr(characteristicFile.getId()));
        }
        smartParkVisitor.setAccessDateType(1);
        smartParkVisitor.setAccessStartDate(DateUtil.beginOfDay(new Date()));
        smartParkVisitor.setAccessEndDate(DateUtil.parse(DateUtil.format(new Date(), "yyyy-MM-dd")+" 23:59:59"));
        if(StringUtils.isNotEmpty(smartParkVisitors)){
            smartParkVisitor.setId(smartParkVisitors.get(0).getId());
            if(!smartParkVisitors.get(0).getSourceSystem().contains(vo.getDeviceCode())){
                smartParkVisitor.setSourceSystem(smartParkVisitors.get(0).getSourceSystem()+","+vo.getDeviceCode());
            }
            smartParkVisitorMapper.updateByPrimaryKeySelective(smartParkVisitor);
        }else {
            smartParkVisitor.setSourceSystem(vo.getDeviceCode());
            smartParkVisitorMapper.insertSelective(smartParkVisitor);
        }
        //人脸就下发权限
        if(vo.getOpenType()==0){
            //授权
            //查访客配置
            List<String>devices = new ArrayList<>();
            SmartParkUserTzVO smartParkUserTzVO = new SmartParkUserTzVO();
            if(StringUtils.isNotEmpty(strategyConfig.getDeviceCodes())){
                String[] deviceAreas = strategyConfig.getDeviceCodes().split(",");
                for(String s : deviceAreas){
                    SmartDeviceRpcQO smartDeviceRpcQO = new SmartDeviceRpcQO();
                    smartDeviceRpcQO.setDeviceAreaCode(s);
                    smartDeviceRpcQO.setOrgCode(vo.getOrgCode());
                    smartDeviceRpcQO.setTenantId(strategyConfig.getTenantId());
                    smartDeviceRpcQO.setNeedPage(false);
                    CommonResponseBody<List<SmartDeviceDTO>> smartParkDeviceRpcServiceDevices = smartParkDeviceRpcService.getDevices(smartDeviceRpcQO);
                    if(!smartParkDeviceRpcServiceDevices.isSuccess() || StringUtils.isEmpty(smartParkDeviceRpcServiceDevices.getData())){
                        continue;
                    }
                    List<SmartDeviceDTO> smartDeviceDTOS = smartParkDeviceRpcServiceDevices.getData();
                    for (SmartDeviceDTO smartDeviceDTO : smartDeviceDTOS){
                        devices.add(smartDeviceDTO.getDeviceCode());
                    }
                }

                smartParkUserTzVO.setUserId(smartParkVisitor.getId());
                smartParkUserTzVO.setUserType(2);
                smartParkUserTzVO.setPhoneNum(smartParkVisitor.getVisitorPhoneNum());
                smartParkUserTzVO.setUserName(smartParkVisitor.getVisitorName());
                smartParkUserTzVO.setCharacteristic(smartParkVisitor.getCharacteristic());
                if(smartParkVisitor.getAccessDateType()==1) {
                    smartParkUserTzVO.setAccessStartDate(DateUtil.beginOfDay(new Date()));
                    smartParkUserTzVO.setAccessEndDate(DateUtil.parse(DateUtil.format(new Date(), "yyyy-MM-dd")+" 23:59:59"));
                }
                smartParkUserTzVO.setGmtModified(smartParkVisitor.getGmtModified()==null?smartParkVisitor.getGmtCreate():smartParkVisitor.getGmtModified());
                String device = ArrayUtil.join(devices.toArray(),",");
                //下发设备
                smartParkDeviceAuthService.sendMqtt(MqttOptType.ADDUSERFACE.getOptCode(),device,smartParkUserTzVO,MqttTopicType.ACCESSCONTROL.getTopicCode());
            }
        }
        smartParkVisitor.setOpenType(vo.getOpenType());
        //动态id  存入redis
        String uid = RandomUtil.randomString(16);
        if(vo.getOpenType()==4){
            redisService.set(uid,smartParkVisitor,60*60*24);
        }else if(vo.getOpenType()==2){
            redisService.set(uid,smartParkVisitor,5*60);
        }
        return ResponseBodyWrapperUtil.successWrapper(uid);
    }

    /**
     * 修改访客管理
     * 
     * @param vo 访客管理
     * @return 结果
     */
    @Override
    public CommonResponseBody<Boolean> updateSmartParkVisitor(SmartParkVisitorVO vo)
    {
        // 验证 todo
        SmartParkVisitor smartParkVisitor = new SmartParkVisitor();
        try {
            BeanUtil.insertConversion(vo, smartParkVisitor);
        } catch (Exception e) {
            logger.error("", e);
        }
        smartParkVisitor.beforeUpdate();
        return ResponseBodyWrapperUtil.toResData(smartParkVisitorMapper.updateByPrimaryKeySelective(smartParkVisitor));
    }

    /**
     * 删除访客管理信息
     * 
     * @param vo 访客管理
     * @return 结果08
     */
    @Override
    public CommonResponseBody<Boolean> deleteSmartParkVisitor(SmartParkVisitorVO vo)
    {
        // 验证 todo
        if(StringUtils.isNull(vo.getId())){
            return ResponseBodyWrapperUtil.fail(ErrMsgEnum.ERROR_PARAME);
        }
        SmartParkVisitor smartParkVisitor = new SmartParkVisitor();
        try {
            BeanUtil.insertConversion(vo, smartParkVisitor);
        } catch (Exception e) {
            logger.error("", e);
        }
        smartParkVisitor.beforeDelete();
        return ResponseBodyWrapperUtil.toResData(smartParkVisitorMapper.updateByPrimaryKeySelective(smartParkVisitor));
    }

    /**
     *  获取访客二维码链接
     *
     * @param qo 访客管理
     * @return 访客管理
     */
    @Override
    public CommonResponseBody<SmartParkVisitorVO> getQrCodeByVisitor(SmartParkVisitorQO qo)
    {
        if(StringUtils.isEmpty(qo.getVisitorPhoneNum())){
            return ResponseBodyWrapperUtil.fail("手机号为空","98001");
        }
        if(StringUtils.isEmpty(qo.getTenantId())){
            return ResponseBodyWrapperUtil.fail("租户ID为空","98002");
        }
        //查询该租户开门方式是否支持二维码开门
        SmartParkStrategyConfigExample smartParkStrategyConfigExample = new SmartParkStrategyConfigExample();
        SmartParkStrategyConfigExample.Criteria criteria = smartParkStrategyConfigExample.createCriteria();
        criteria.andTenantIdEqualTo(qo.getTenantId());
        List<SmartParkStrategyConfig> strategyConfigs = smartParkStrategyConfigMapper.selectByExample(smartParkStrategyConfigExample);
        if(StringUtils.isEmpty(strategyConfigs)){
            return ResponseBodyWrapperUtil.fail("该租户未做访客配置","98003");
        }

        SmartParkStrategyConfig strategyConfig = strategyConfigs.get(0);
        String openType = strategyConfig.getOpenType();
        SmartParkVisitorExample smartParkVisitorExample = new SmartParkVisitorExample();
        SmartParkVisitorExample.Criteria criteria1 = smartParkVisitorExample.createCriteria();
        if (qo.getTenantId() != null) {
            criteria1.andTenantIdEqualTo(qo.getTenantId());
        }
        criteria1.andIsDeletedEqualTo(0);
        criteria1.andVisitorPhoneNumEqualTo(qo.getVisitorPhoneNum());
        smartParkVisitorExample.setOrderByClause("gmt_create desc");
        List<SmartParkVisitor> passRecords = smartParkVisitorMapper.selectByExample(smartParkVisitorExample);
        if(StringUtils.isEmpty(passRecords) || passRecords.size()==0){
            return ResponseBodyWrapperUtil.fail("该手机号未登记","400");
        }
        SmartParkVisitor smartParkVisitor = passRecords.get(0);

        if(StringUtils.isEmpty(openType) || openType.indexOf(Convert.toStr(smartParkVisitor.getOpenType()))==-1) {
            return ResponseBodyWrapperUtil.fail("不支持此开门方式", "400");
        }

        if(!DateUtil.isIn(new Date(),smartParkVisitor.getAccessStartDate(),smartParkVisitor.getAccessEndDate())){
            return ResponseBodyWrapperUtil.fail("不在访问日期内","400");
        }

        if(smartParkVisitor.getOpenType()!=2) {
            return ResponseBodyWrapperUtil.fail("不支持二维码开门", "400");
        }

            //动态id  存入redis   20秒过期
        String uid = RandomUtil.randomString(16);
        redisService.set(uid,smartParkVisitor,20);
        smartParkVisitor.setUid(uid);
        return ResponseBodyWrapperUtil.successWrapper(smartParkVisitor,SmartParkVisitorVO.class);
    }

    /**
     * 访客二维码开门验证
     * @param vo
     * @return
     * @throws Exception
     */
    @Override
    public CommonResponseBody<SmartParkVisitorQrVO> qrCodeVerify(DevicePullDataVo vo) throws Exception {
        String deviceCode = vo.getDeviceCode();
        String uid = vo.getUid();
        // 验证
        if(StringUtils.isNull(uid)){
            return ResponseBodyWrapperUtil.fail(ErrMsgEnum.ERROR_PARAME);
        }
        if(StringUtils.isNull(deviceCode)){
            return ResponseBodyWrapperUtil.fail(ErrMsgEnum.ERROR_PARAME);
        }

        //验证redis是否存在动态uid  顺便查出响应访客并比对
        SmartParkVisitor smartParkVisitor = (SmartParkVisitor)redisService.get(uid);
        if(StringUtils.isNull(smartParkVisitor)){
            return ResponseBodyWrapperUtil.fail("二维码已失效","400");
        }

        if(!DateUtil.isIn(new Date(),smartParkVisitor.getAccessStartDate(),smartParkVisitor.getAccessEndDate())){
            return ResponseBodyWrapperUtil.fail("不在访问日期内","400");
        }
        //是否有设备权限
        //查询该租户开门方式是否支持二维码开门
        SmartParkStrategyConfigExample smartParkStrategyConfigExample = new SmartParkStrategyConfigExample();
        SmartParkStrategyConfigExample.Criteria criteria = smartParkStrategyConfigExample.createCriteria();
        criteria.andTenantIdEqualTo(smartParkVisitor.getTenantId());
        List<SmartParkStrategyConfig> strategyConfigs = smartParkStrategyConfigMapper.selectByExample(smartParkStrategyConfigExample);
        if(StringUtils.isEmpty(strategyConfigs)){
            return ResponseBodyWrapperUtil.fail("无设备权限","400");
        }

        SmartParkStrategyConfig strategyConfig = strategyConfigs.get(0);
        if(StringUtils.isEmpty(strategyConfig.getDeviceCodes())){
            return ResponseBodyWrapperUtil.fail("无区域权限","400");
        }
        //查询设备区域  之前设计的是访客配置绑定设备  现在设计成绑定区域  区域绑定设备
        String[] areas = strategyConfig.getDeviceCodes().split(",");
        for(String s : areas){
            //用区域查询设备
            SmartDeviceRpcQO smartDeviceRpcQO = new SmartDeviceRpcQO();
            smartDeviceRpcQO.setDeviceAreaCode(s);
            smartDeviceRpcQO.setOrgCode(vo.getOrgCode());
            smartDeviceRpcQO.setTenantId(vo.getTenantId());
            smartDeviceRpcQO.setNeedPage(false);
            CommonResponseBody<List<SmartDeviceDTO>> smartParkDeviceRpcServiceDevices = smartParkDeviceRpcService.getDevices(smartDeviceRpcQO);
            if(!smartParkDeviceRpcServiceDevices.isSuccess() || StringUtils.isEmpty(smartParkDeviceRpcServiceDevices.getData())){
                continue;
            }
            //比对当前设备是否等于查询出的区域设备
            for(SmartDeviceDTO smartDeviceDTO:smartParkDeviceRpcServiceDevices.getData()){
                if(deviceCode.equals(smartDeviceDTO.getDeviceCode())){
                    if(smartParkVisitor.getOpenType()==2){
                        //删除redi缓存
                        redisService.del(uid);
                    }
                    SmartParkVisitorQrVO smartParkVisitorQrVO = new SmartParkVisitorQrVO();
                    smartParkVisitorQrVO.setUserId(smartParkVisitor.getId());
                    smartParkVisitorQrVO.setVisitorName(smartParkVisitor.getVisitorName());
                    smartParkVisitorQrVO.setVisitorPhoneNum(smartParkVisitor.getVisitorPhoneNum());
                    return ResponseBodyWrapperUtil.successWrapper(smartParkVisitorQrVO);
                }
            }
        }
        return ResponseBodyWrapperUtil.fail("无设备权限","400");
    }
}
